package com.tfblog.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.tfblog.blog.entity.Blog;
import com.tfblog.blog.entity.Tag;
import com.tfblog.blog.mapper.BlogMapper;
import com.tfblog.blog.service.BlogService;
import com.tfblog.blog.vo.DayCount;
import com.tfblog.blog.vo.TimeVO;
import com.tfblog.utils.Constant;
import com.tfblog.utils.PageUtils;
import com.tfblog.utils.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tfeng
 * @since 2021-04-26
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    private BlogMapper blogMapper;


    /*
    * 分页查询博客内容 : 可以带搜素关键词("key字段")
    * */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        //获取params中的key属性
        String key = (String)params.get("key");
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        //我们匹配key字段是否为空 : 如果存在,则对博客的标题进行模糊匹配查找
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("title",key);
        }
        wrapper.eq("published",1);

        //创建IPage对象 : SpringBoot用于进行分页展示的
        IPage<Blog> page = this.page(
          new Query<Blog>().getPage(params),
          wrapper
        );
        return new PageUtils(page);
    }

    /*
    * 根据分类id查询指定的博客信息: 分页显示
    * */
    @Override
    public PageUtils queryPageByTypeId(Long typeId, Map<String, Object> params) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        //获取params中的key属性
        String key = (String)params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("title",key);
        }
        wrapper.eq("type_id",typeId).eq("published",1);
        IPage<Blog> page = this.page(
            //初始化当前页和每页显示的条数
            new Query<Blog>().getPage(params),
            wrapper
        );
        return new PageUtils(page);
    }


    /*
    * 根据分类id查询查询所有的博客信息
    * */
    @Override
    public List<Blog> selectBlogsByTypeId(Long id) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("type_id",id).eq("published",1);
        List<Blog> blogList = blogMapper.selectList(wrapper);
        return blogList;
    }



    /*
    * 根据标签id进行联表查询 : 使用 mybatis完成联表查询...
    * */
    @Override
    public PageUtils queryPageByTag(Long typeId, Map<String, Object> params) {
        //默认不传参数,从第一页查询10条数据
        long curPage = 1;
        long limit = 10;
        if(params.get(Constant.PAGE) != null){
            curPage = Long.parseLong((String)params.get(Constant.PAGE));
        }
        if(params.get(Constant.LIMIT) != null){
            limit = Long.parseLong((String)params.get(Constant.LIMIT));
        }
        //定义分页的Page对象
        Page<Blog> page = new Page<>(curPage, limit);
        //初始化分页查询的结果集
        List<Blog> blogList = null;
        String key = (String)params.get("key");
        if (!StringUtils.isEmpty(key)) {
            //说明带有key的搜索条件
            key = "%" + key + "%";
            blogList = blogMapper.queryPageByTagSearch(page,key,typeId);
        }else {
            blogList = blogMapper.queryPageByTag(page, typeId);
        }
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(blogList);
        return pageUtils;
    }

    /*
    * 根据标签id查询所有的博客信息
    * */
    @Override
    public List<Blog> selectBlogsByTagId(Long id) {
        List<Blog> blogList = blogMapper.queryPageByTagId(id);
        return blogList;
    }

    /*
    * 根据博客id与绑定的标签ids,进行中间表的维护
    * */
    @Transactional
    @Override
    public void saveBlogIdAndTagIds(Long blogId, Long[] tagIds) {
        //依次将外键绑定关系插入到外键表中
        for (Long tagId : tagIds) {
            blogMapper.insertBlogAndTagId(blogId,tagId);
        }
    }

    /*
    * 根据分类id/标签id查询对应的博客信息
    * */
    @Override
    public Blog selectBlogById(Long blogId, Long tId, Long styleId) {
        if (styleId == 0) {
            //传递的是分类的id
            QueryWrapper<Blog> wrapper = new QueryWrapper<>();
            wrapper.eq("id",blogId).eq("type_id",tId);
            Blog blog = blogMapper.selectOne(wrapper);
            return blog;
        }else {
            //传递的是标签的id
            Blog blog = blogMapper.selectBlogByTagId(blogId, tId);
            return blog;
        }
    }

    /*
    * 根据博客id查询对应的标签信息
    * */
    @Override
    public List<Tag> selectTagsByBlogId(Long id) {
        List<Tag> tags = blogMapper.selectTagsByBlogId(id);
        return tags;
    }

    /*
    * 进行博客与标签的更新工作
    * */
    @Transactional
    @Override
    public void updateBlogIdAndTagIds(Long blogId, Long[] tagIds) {
        //首先,我们需要将之前的blogId绑定的tagId删除
        blogMapper.deleteBlogAndTags(blogId);
        if (tagIds.length != 0) {
            //将新的博客id与标签id的关系保存到外键表中
            saveBlogIdAndTagIds(blogId,tagIds);
        }
    }

    /*
    * 根据博客id删除指定的博客 : 逻辑删除
    * */
    @Transactional
    @Override
    public void deleteBlog(Long id) {
        //逻辑删除博客 : 将其deleted置为1
        blogMapper.deleteById(id);
        //TODO 此时我们的博客和标签的id不会删除维护,保存在外键表中应该可以
    }

    /*
    * 分页显示草稿信息
    * */
    @Override
    public PageUtils qureryPageDraft(Map<String, Object> params) {
        //获取params中的key属性
        String key = (String)params.get("key");
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        //我们匹配key字段是否为空 : 如果存在,则对博客的标题进行模糊匹配查找
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("title",key);
        }
        //增加草稿判断信息
        wrapper.eq("published",0);

        //创建IPage对象 : SpringBoot用于进行分页展示的
        IPage<Blog> page = this.page(
                new Query<Blog>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    /*
    * 分页获取热门博客数据
    * */
    @Override
    public PageUtils queryHotBlogs(Map<String, Object> params) {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("recommend",1).eq("published",1);
        IPage<Blog> page = this.page(
                //初始化当前页和每页显示的条数
                new Query<Blog>().getPage(params),
                wrapper
        );
        return new PageUtils(page);

    }

    /*
    * 根据博客id查询博客详情
    * */
    @Override
    public Blog selectDetailsById(Long id) {
        Blog blog = blogMapper.selectById(id);
        return blog;
    }

    /*
    * 根据年和月份信息查询指定博客
    * 使用原生mysql语句完成
    * */
    @Override
    public List<TimeVO> findTimeInfo(Long year, Long month) {
        List<TimeVO> blogList = blogMapper.selectTimeInfo(year,month);
        return blogList;
    }

    /*
    * 查找不同分类的博客数
    * */
    @Override
    public int findBlogCountByTypeId(Long id) {
        int count = blogMapper.selectBlogCountByTypeId(id);
        return count;
    }

    /*
    * 查找不同标签的博客数
    * */
    @Override
    public int findBlogCountByTagId(Long id) {
        int count = blogMapper.selectBlogCountByTagId(id);
        return count;
    }

    /*
    * 查找指定年份每一天对应的博客数量
    * */
    @Override
    public List<DayCount> findEveryDayBlogCount(Long year) {
        List<DayCount> list = blogMapper.selectEveryDayBlogCount(year);
        return list;
    }

    /*
    * 获取最新的十篇博客
    * */
    @Override
    public PageUtils queryNewBlogs() {
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        wrapper.eq("published",1);
        wrapper.orderByDesc("create_time");
        Map<String, Object> params = new HashMap<>();
        IPage<Blog> page = this.page(
                //初始化当前页和每页显示的条数
                new Query<Blog>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    /*
    * 返回最小的年份(存在发布博客)
    * */
    @Override
    public Long findMinYear() {
        return blogMapper.selectMinYear();
    }

    /*
    * 根据博客id查询对应的博客
    * */
    @Override
    public Blog findBlogById(Long blogId) {
        Blog blog = blogMapper.selectById(blogId);
        return blog;
    }

}
